package concurrent.juc.reentrantlock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: 黄嘉振
 * @create: 2023/6/15 15:37
 * @description:
 **/
public class LockInterruptiblyDemo {
    private static ReentrantLock lock1 = new ReentrantLock();
    private static ReentrantLock lock2 = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        // 入参相反导致死锁
        Thread t1 = new Thread(new ReentrantLockThread(lock1, lock2));
        Thread t2 = new Thread(new ReentrantLockThread(lock2, lock1));
        t1.start();
        t2.start();
        TimeUnit.MILLISECONDS.sleep(100);
        System.out.println("main 线程睡眠 1 秒");
        TimeUnit.MILLISECONDS.sleep(1000);
        System.out.println("main 线程执行 t1 interrupt");
        t1.interrupt();
    }

    static class ReentrantLockThread implements Runnable {
        private ReentrantLock lock1, lock2;

        public ReentrantLockThread(ReentrantLock lock1, ReentrantLock lock2) {
            this.lock1 = lock1;
            this.lock2 = lock2;
        }

        @Override
        public void run() {
            try {
                // 对lock1加锁
                lock1.lockInterruptibly();
                System.out.println(Thread.currentThread().getName() + " 线程加锁成功 1-2");
                // 等待lock1 lock2 分别被两个线程获取产生死锁现象
                TimeUnit.MILLISECONDS.sleep(100);
                lock2.lockInterruptibly();
                System.out.println(Thread.currentThread().getName() + " 线程加锁成功 2-2");
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "发生异常：");
                e.printStackTrace();
            } finally {
                if (lock1.isHeldByCurrentThread()) {
                    lock1.unlock();
                }
                if (lock2.isHeldByCurrentThread()) {
                    lock2.unlock();
                }
                System.out.println(Thread.currentThread().getName() + "解锁成功！");
            }
        }
    }
}
